#include	"../Headers/types.h"			/*  */
#include	"../Headers/config.h"			/*  */
#include	"../Headers/log.h"			/*  */
#include "fs.file.h"
#include <string>
#include <memory.h>
#include <iostream>
#include <ostream>
#include <istream>
#include <algorithm>
#include <fstream>

using namespace TOB;

File::File()  {}
File::~File() {}

Code::Type File::write(std::string fileName, std::string data) {
	std::ofstream out;
	out.open(fileName.c_str(), std::ofstream::binary | std::ios::app);
	if (!out) { return Code::FS_FunctionCallFailure; }
	out.write(data.c_str(), data.length());
	out.close();
	return Code::Okay;
}

Code::Type File::write(std::string fileName, char * data, uint32 count) {
	std::ofstream out;
	out.open(fileName.c_str(), std::ofstream::binary | std::ios::app);
	if (!out) { return Code::FS_FunctionCallFailure; }
	out.write(data, count);
	out.close();
	return Code::Okay;
}

Code::Type File::read(std::string fileName, std::string& source, uint16 size, uint32 pos) {
	std::ifstream in;
	char * data = new char[size];
	in.open(fileName.c_str(), std::ifstream::binary);
	if (!in)		 { return Code::FS_FunctionCallFailure;				 }
	if (pos < 0) { in.seekg(0, std::ios::end);						 		 }
	if (pos > 0) { in.seekg(std::streampos(pos));   					 }
	if (pos == 0){ in.seekg(0, std::ios::beg); 							 	 }
	if (size < 0){ size = in.tellg(); in.seekg(std::ios::beg); }
	memset(data, 0, size);
	in.read(data, size);
	source.assign(data, size);
	delete[] data;
	data = NULL;
	in.close();
	return Code::Okay;
}

Code::Type File::read(std::string fileName, char * source, uint16 size, uint32 pos, uint16 * rbytes) {
	std::ifstream in;
	char * data = new char[size];
	in.open(fileName.c_str(), std::ifstream::binary);
	if (!in)		 { return Code::FS_FunctionCallFailure;				 }
	if (pos < 0) { in.seekg(0, std::ios::end);						 		 }
	if (pos > 0) { in.seekg(std::streampos(pos));   					 }
	if (pos == 0){ in.seekg(0, std::ios::beg); 							 	 }
  if (size < 0){ size = in.tellg(); in.seekg(std::ios::beg); }
	memset(data, 0, size);
	in.read(data, size);
	*rbytes = in.gcount();
	memcpy(source, data, in.gcount());
	delete[] data;
	data = NULL;
	in.close();
	return Code::Okay;
}

uint32 File::get_file_size(std::string fileName) {
	std::ifstream in;
	in.open(fileName.c_str(), std::ifstream::binary);
	in.seekg(0, std::ios::end);
	long length = in.tellg();
	in.close();
	return static_cast<uint32>(length);
}

std::string File::search(std::string fileName, std::string s) {
	std::ifstream in;
	std::string line;
	in.open(fileName);
	while (getline(in, line)) {
		if (std::search(line.begin(), line.end(), s.begin(), s.end()) != line.end()) {
			return line;
		}
	}
	return "";
}

Code::Type File::exists(std::string fileName) {
	std::ifstream in;
	in.open(fileName);
	if (!in) { return Code::FS_FunctionCallFailure; }
	return Code::Okay;
}
